package com.enation.app.javashop.core.trade.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dag.eagleshop.core.delivery.model.dto.JsonBean;
import com.dag.eagleshop.core.delivery.service.DeliveryManager;
import com.enation.app.javashop.core.aftersale.model.dos.RefundDO;
import com.enation.app.javashop.core.aftersale.model.dto.RefundDTO;
import com.enation.app.javashop.core.aftersale.model.vo.RefundQueryParamVO;
import com.enation.app.javashop.core.aftersale.service.AfterSaleManager;
import com.enation.app.javashop.core.base.SettingGroup;
import com.enation.app.javashop.core.base.model.enums.YesNoEnum;
import com.enation.app.javashop.core.client.system.SettingClient;
import com.enation.app.javashop.core.distribution.model.dos.DistributionOrderDO;
import com.enation.app.javashop.core.distribution.service.DistributionManager;
import com.enation.app.javashop.core.distribution.service.DistributionOrderManager;
import com.enation.app.javashop.core.goods.model.vo.GoodsSkuVO;
import com.enation.app.javashop.core.goods.service.GoodsSkuManager;
import com.enation.app.javashop.core.member.model.dos.LeaderDO;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.service.LeaderManager;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.promotion.fulldiscount.model.dos.FullDiscountGiftDO;
import com.enation.app.javashop.core.promotion.pintuan.model.PintuanOrderDetailVo;
import com.enation.app.javashop.core.promotion.pintuan.service.PintuanOrderManager;
import com.enation.app.javashop.core.shop.model.vo.ShopVO;
import com.enation.app.javashop.core.shop.service.ShopManager;
import com.enation.app.javashop.core.trade.TradeErrorCode;
import com.enation.app.javashop.core.trade.cart.model.vo.CouponVO;
import com.enation.app.javashop.core.trade.order.model.dos.OrderDO;
import com.enation.app.javashop.core.trade.order.model.dos.OrderItemsDO;
import com.enation.app.javashop.core.trade.order.model.dos.OrderMetaDO;
import com.enation.app.javashop.core.trade.order.model.dos.SortingSerial;
import com.enation.app.javashop.core.trade.order.model.dto.OrderDetailQueryParam;
import com.enation.app.javashop.core.trade.order.model.dto.OrderLineDTO;
import com.enation.app.javashop.core.trade.order.model.dto.OrderQueryParam;
import com.enation.app.javashop.core.trade.order.model.enums.*;
import com.enation.app.javashop.core.trade.order.model.vo.*;
import com.enation.app.javashop.core.trade.order.service.OrderMetaManager;
import com.enation.app.javashop.core.trade.order.service.OrderQueryManager;
import com.enation.app.javashop.core.trade.sdk.model.OrderDetailDTO;
import com.enation.app.javashop.core.trade.sdk.model.OrderSkuDTO;
import com.enation.app.javashop.core.trade.sdk.model.OrderVerificationDTO;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Buyer;
import com.enation.app.javashop.framework.util.*;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * 订单查询业务实现类
 *
 * @author Snow create in 2018/5/14
 * @version v2.0
 * @since v7.0.0
 */
@Service
public class OrderQueryManagerImpl implements OrderQueryManager {

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private AfterSaleManager afterSaleManager;

    @Autowired
    private OrderMetaManager orderMetaManager;

    @Autowired
    private SettingClient settingClient;

    @Autowired
    private LeaderManager leaderManager;

    @Autowired
    private DistributionManager distributionManager;

    @Autowired
    private DistributionOrderManager distributionOrderManager;

    @Autowired
    private MemberManager memberManager;

    @Autowired
    private GoodsSkuManager goodsSkuManager;

    @Autowired
    private ShopManager shopManager;

    @Autowired
    private PintuanOrderManager pintuanOrderManager;

    @Autowired
    private DeliveryManager deliveryManager;

    /**
     * 日志记录
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Page list(OrderQueryParam paramDTO) {
        // 分页查询订单
        Page<OrderDO> page = getOrderDOByPage(paramDTO);


        //订单自动取消天数(平台配置)
        int cancelLeftDay = getCancelLeftDay();

        // DO 转为 VO
        List<OrderDO> orderList = page.getData();

        List<OrderLineVO> lineList = transOrderDOToOrderLineVO(cancelLeftDay, orderList);

        // 生成新的Page
        long totalCount = page.getDataTotal();
        Page<OrderLineVO> linePage = new Page(paramDTO.getPageNo(), totalCount, paramDTO.getPageSize(), lineList);

        return linePage;
    }

    @Override
    public Page listDistributionOrder(OrderQueryParam paramDTO) {
        StringBuffer sql = new StringBuffer(" SELECT o.*, d.member_id_lv1, d.audit_status AS my_distribution_audit_status, " +
                " d.`status` AS my_distribution_status, m.real_name AS lv1_member_nick_name, m.mobile AS lv1_member_mobile, " +
                " esd.audit_status AS up_distribution_audit_status, esd.`status` AS up_distribution_status, " +
                " me.nickname AS member_nick_name, me.real_name AS my_real_name, me.mobile AS my_mobile,sd.cooperation_mode, " +
                " sd.settlement_method FROM es_order o " +
                " LEFT JOIN es_distribution d ON o.member_id = d.member_id " +
                " LEFT JOIN es_distribution esd ON d.member_id_lv1 = esd.member_id " +
                " LEFT JOIN es_member m ON d.member_id_lv1 = m.member_id " +
                " LEFT JOIN es_member me ON me.member_id = o.member_id " +
                " LEFT JOIN es_shop_detail sd ON o.seller_id = sd.shop_id WHERE o.disabled = 0 ");

        List<Object> term = composeSql(paramDTO, sql);

        // 先按PO进行查询
        Page page = daoSupport.queryForPage(sql.toString(), paramDTO.getPageNo(), paramDTO.getPageSize(),
                OrderLineVO.class, term.toArray());
        // 自己是团长的, 团长信息显示自己的
        List<OrderLineVO> list = page.getData();
        for (OrderLineVO orderLineVO : list) {

            Integer upDistributionAuditStatus = orderLineVO.getUpDistributionAuditStatus();
            Integer upDistributionStatus = orderLineVO.getUpDistributionStatus();
            // 上级没有成为团长 不显示
            if(upDistributionAuditStatus == null || upDistributionStatus == null || upDistributionAuditStatus != 2 ||upDistributionStatus != 1){
                orderLineVO.setLv1MemberNickName(null);
                orderLineVO.setLv1MemberMobile(null);
            }

            Integer myDistributionAuditStatus = orderLineVO.getMyDistributionAuditStatus();
            Integer myDistributionStatus = orderLineVO.getMyDistributionStatus();
            String myRealName = orderLineVO.getMyRealName();
            String myMobile = orderLineVO.getMyMobile();

            // 查看自己是不是团长, 自己是团长 显示自己的团长信息
            if(myDistributionAuditStatus != null && myDistributionStatus != null && myDistributionAuditStatus == 2 && myDistributionStatus == 1 ){
                orderLineVO.setLv1MemberNickName(myRealName);
                orderLineVO.setLv1MemberMobile(myMobile);
            }

            // 转换店铺 合作模式文字  结算方式文字
            String cooperationModeLabel = DictUtils.getDictLabel(null, orderLineVO.getCooperationMode(), "COOPERATION_MODE");
            String settlementMethodLabel = DictUtils.getDictLabel(null, orderLineVO.getSettlementMethod(), "SETTLEMENT_METHOD");
            orderLineVO.setCooperationModeLabel(cooperationModeLabel);
            orderLineVO.setSettlementMethodLabel(settlementMethodLabel);
        }
        page.setData(list);
        return page;
    }

    @Override
    public List<OrderItemsDO> listOrderSku(OrderQueryParam orderQueryParam) {
        StringBuffer sql = new StringBuffer(" select s.* from  es_order_items s LEFT JOIN  es_order o  on o.sn = s.order_sn  where 1=1 ");

        List<Object> term = new ArrayList<>();
        // sku_id
        if (orderQueryParam.getSkuId()!=null) {
            sql.append(" and s.product_id = ?");
            term.add(orderQueryParam.getSkuId());
        }
        // member_id
        if (orderQueryParam.getMemberId()!=null) {
            sql.append(" and o.member_id = ?");
            term.add(orderQueryParam.getMemberId());
        }

        // 需要排除的订单状态
        if (!StringUtil.isEmpty(orderQueryParam.getAntiOrderStatus())) {
            sql.append(" and o.order_status != ?");
            term.add(orderQueryParam.getAntiOrderStatus());
        }

        // 订单状态
        if (!StringUtil.isEmpty(orderQueryParam.getOrderStatus())) {
            sql.append(" and o.order_status = ?");
            term.add(orderQueryParam.getOrderStatus());
        }

        // 售后状态
        if (!StringUtil.isEmpty(orderQueryParam.getServiceStatus())) {
            sql.append(" and o.service_status = ?");
            term.add(orderQueryParam.getServiceStatus());
        }

        // 按时间查询
        Long startTime = orderQueryParam.getStartTime();
        Long endTime = orderQueryParam.getEndTime();
        if (startTime != null) {
            String startDay = DateUtil.toString(startTime, "yyyy-MM-dd");
            sql.append(" and o.create_time >= ?");
            term.add(DateUtil.getDateline(startDay + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
        }

        if (endTime != null) {
            String endDay = DateUtil.toString(endTime, "yyyy-MM-dd");
            sql.append(" and o.create_time <= ?");
            term.add(DateUtil.getDateline(endDay + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
        }

        // 先按PO进行查询
        return daoSupport.queryForList(sql.toString(), OrderItemsDO.class, term.toArray());

    }

    private List<OrderLineVO> transOrderDOToOrderLineVO(int cancelLeftDay, List<OrderDO> orderList) {
        List<OrderLineVO> lineList = new ArrayList();
        for (OrderDO orderDO : orderList) {
            OrderLineVO line = new OrderLineVO(orderDO);

            //如果未付款并且是在线支付则显示取消时间
            if (!PayStatusEnum.PAY_YES.value().equals(orderDO.getPayStatus())
                    && PaymentTypeEnum.ONLINE.value().equals(orderDO.getPaymentType())
                    && !OrderStatusEnum.CANCELLED.value().equals(orderDO.getOrderStatus())) {
                //计算自动取消剩余时间
                Long leftTime = getCancelLeftTimeByMinute(line.getCreateTime(), cancelLeftDay);
                line.setCancelLeftTime(leftTime);
            } else {
                line.setCancelLeftTime(0L);
            }


            if (OrderTypeEnum.pintuan.name().equals(line.getOrderType())) {

                //如果订单
                int waitNums = convertOwesNumss(orderDO);
                line.setWaitingGroupNums(waitNums);
                if (waitNums == 0 && PayStatusEnum.PAY_YES.value().equals(line.getPayStatus())) {
                    line.setPingTuanStatus("已成团");
                } else if (OrderStatusEnum.CANCELLED.value().equals(line.getOrderStatus())) {
                    line.setPingTuanStatus("未成团");
                } else {
                    line.setPingTuanStatus("待成团");
                }
            }

            //判单当前订单是不是服务订单
            //默认当前订单不是服务订单
            line.setIsVirtualOrder(YesOrNoEnums.NO.getIndex());
            //默认不显示核销码按钮，如果在可用时间范围内则显示
            line.setVirtualStatus(YesOrNoEnums.NO.getIndex());
            //如果有过期时间就说明是服务订单
            if (line.getExpiryDay() != null) {
                line.setIsVirtualOrder(YesOrNoEnums.YES.getIndex());
                if(this.queryVerificationStatus(orderDO)!=VerificationCodeStatusEnum.CANCELLED.getIndex()){
                    line.setVirtualStatus(YesOrNoEnums.YES.getIndex());
                }
            }

            lineList.add(line);
        }
        return lineList;
    }

    private Page<OrderDO> getOrderDOByPage(OrderQueryParam paramDTO) {
        StringBuffer sql = new StringBuffer("select * from es_order o where disabled=0 ");

        List<Object> term = composeSql(paramDTO, sql);

        // 先按PO进行查询
        return daoSupport.queryForPage(sql.toString(), paramDTO.getPageNo(), paramDTO.getPageSize(),
                OrderDO.class, term.toArray());
    }

    private List<Object> composeSql(OrderQueryParam paramDTO, StringBuffer sql) {
        List<Object> term = new ArrayList<>();
        String keywords = paramDTO.getKeywords();
        if (StringUtil.notEmpty(keywords)) {
            sql.append(" and (o.sn like ? or o.items_json like ? )");
            term.add("%" + keywords + "%");
            term.add("%" + keywords + "%");
        }

        // 会员昵称查询
        String nickName = paramDTO.getNickName();
        if (StringUtil.notEmpty(nickName)) {
            sql.append(" and m.nickname like ? ");
            term.add("%"+nickName+"%");
        }
        // 团长名称查询
        String leaderName = paramDTO.getLv1MemberNickName();
        if (StringUtil.notEmpty(leaderName)) {
            sql.append(" and m.real_name like ? ");
            term.add("%"+leaderName+"%");
        }
        // 团长手机号
        String leaderMobile = paramDTO.getLv1MemberMobile();
        if (StringUtil.notEmpty(leaderMobile)) {
            sql.append(" and m.mobile = ? ");
            term.add(leaderMobile);
        }
        // 收货人手机号
        String shipMobile = paramDTO.getShipMobile();
        if (StringUtil.notEmpty(shipMobile)) {
            sql.append(" and o.ship_mobile = ? ");
            term.add(shipMobile);
        }

        // 按卖家查询
        Integer sellerId = paramDTO.getSellerId();
        if (sellerId != null) {
            sql.append(" and o.seller_id=?");
            term.add(sellerId);
        }

        // 按会员查询
        Integer memberId = paramDTO.getMemberId();
        if (memberId != null) {
            sql.append(" and o.member_id=?");
            term.add(memberId);
        }

        // 按订单编号查询
        if (StringUtil.notEmpty(paramDTO.getOrderSn())) {
            sql.append(" and o.sn like ?");
            term.add("%" + paramDTO.getOrderSn() + "%");
        }

        // 按交易编号查询
        if (StringUtil.notEmpty(paramDTO.getTradeSn())) {
            sql.append(" and o.trade_sn like ?");
            term.add("%" + paramDTO.getTradeSn() + "%");
        }

        // 按时间查询
        Long startTime = paramDTO.getStartTime();
        Long endTime = paramDTO.getEndTime();
        if (startTime != null) {
            sql.append(" and o.create_time >= ?");
            term.add(startTime);
        }

        if (endTime != null) {
            sql.append(" and o.create_time <= ?");
            term.add(endTime);
        }

        // 按购买人用户名
        String memberName = paramDTO.getBuyerName();
        if (StringUtil.notEmpty(memberName)) {
            sql.append(" and o.member_name like ?");
            term.add("%" + memberName + "%");
        }

        // 按标签查询
        String tag = paramDTO.getTag();
        transTagToSql(tag, sql);

        //订单状态
        if (!StringUtil.isEmpty(paramDTO.getOrderStatus())) {
            sql.append(" and o.order_status = ?");
            term.add(paramDTO.getOrderStatus());
        }

        if (StringUtil.notEmpty(paramDTO.getBuyerName())) {
            sql.append(" and o.items_json like ?");
            term.add("%" + paramDTO.getGoodsName() + "%");
        }
        if (StringUtil.notEmpty(paramDTO.getShipName())) {
            sql.append(" and o.ship_name like ?");
            term.add("%" + paramDTO.getShipName() + "%");
        }
        // 按商品名称查询
        if (StringUtil.notEmpty(paramDTO.getGoodsName())) {
            sql.append(" and o.items_json like ?");
            term.add("%" + paramDTO.getGoodsName() + "%");
        }

        //付款方式
        if (!StringUtil.isEmpty(paramDTO.getPaymentType())) {
            sql.append(" and o.payment_type = ?");
            term.add(paramDTO.getPaymentType());
        }

        //订单来源
        if (!StringUtil.isEmpty(paramDTO.getClientType())) {
            sql.append(" and o.client_type = ?");
            term.add(paramDTO.getClientType());
        }

        //订单类型
        if (!StringUtil.isEmpty(paramDTO.getOrderType())) {
            sql.append(" and o.order_type = ?");
            term.add(paramDTO.getOrderType());
        }

        //订单付款状态
        if (!StringUtil.isEmpty(paramDTO.getPayStatus())) {
            sql.append(" and o.pay_status = ?");
            term.add(paramDTO.getPayStatus());
        }

        //订单金额
        if (paramDTO.getOrderPrice()!=null) {
            sql.append(" and o.order_price >= ?");
            term.add(paramDTO.getOrderPrice());
        }

        // 售后状态

        sql.append(" order by o.order_id desc");
        return term;
    }

    private void transTagToSql(String tag, StringBuffer sql) {
        if (!StringUtil.isEmpty(tag)) {
            OrderTagEnum tagEnum = OrderTagEnum.valueOf(tag);
            switch (tagEnum) {
                case ALL:
                    break;
                //待付款
                case WAIT_PAY:
                    // 非货到付款的，未付款状态的可以结算 OR 货到付款的要发货或收货后才能结算
                    sql.append(" and  ( ( payment_type='cod' and   order_status='" + OrderStatusEnum.ROG + "') ");
                    sql.append(" or order_status = '" + OrderStatusEnum.CONFIRM + "' )");
                    break;

                //待发货
                case WAIT_SHIP:
                    // 普通订单：
                    //      非货到付款的，要已结算才能发货 OR 货到付款的，已确认就可以发货
                    // 拼团订单：
                    //      已经成团的
                    sql.append(" and (order_status='"+OrderStatusEnum.PAID_OFF.name()+"' or order_status='"+OrderStatusEnum.FORMED.name()+"')");
                    break;

                //待收货
                case WAIT_ROG:
                    sql.append(" and o.order_status='" + OrderStatusEnum.SHIPPED + "'");
                    break;

                //已收货
                case ROG:
                        sql.append(" and o.order_status='" + OrderStatusEnum.ROG + "'");
                    break;

                //待评论
                case WAIT_COMMENT:
                    sql.append(" and o.ship_status='" + ShipStatusEnum.SHIP_ROG + "' and o.comment_status='" + CommentStatusEnum.UNFINISHED + "' ");
                    break;

                //待追评
                case WAIT_CHASE:
                    sql.append(" and o.ship_status='" + ShipStatusEnum.SHIP_ROG + "' and o.comment_status='" + CommentStatusEnum.WAIT_CHASE + "' ");
                    break;

                //已取消
                case CANCELLED:
                    sql.append(" and o.order_status='" + OrderStatusEnum.CANCELLED + "'");
                    break;

                //售后中
                case REFUND:
                    sql.append(" and o.service_status='" + ServiceStatusEnum.APPLY + "'");
                    break;

                //已完成
                case COMPLETE:
                    sql.append(" and o.order_status='" + OrderStatusEnum.COMPLETE + "'");
                    break;
                default:
                    break;
            }
        }
    }


    /**
     * 读取订单自动取消天数
     *
     * @return
     */
    private int getCancelLeftDay() {
        String settingVOJson = this.settingClient.get(SettingGroup.TRADE);
        OrderSettingVO settingVO = JsonUtil.jsonToObject(settingVOJson, OrderSettingVO.class);
        int minute = settingVO.getCancelOrderDay();
        return minute;
    }
    /**
     * 读取订单自动收货天数
     *
     * @return
     */
    private int getRogLeftDay() {
        String settingVOJson = this.settingClient.get(SettingGroup.TRADE);
        OrderSettingVO settingVO = JsonUtil.jsonToObject(settingVOJson, OrderSettingVO.class);
        int day = settingVO.getRogOrderDay();
        return day;
    }


    private Long getCancelLeftTime(Long createTime, int rogLeftDay) {

        Long cancelTime = createTime + rogLeftDay * 24 * 60 * 60;
        Long now = DateUtil.getDateline();
        Long leftTime = cancelTime - now;
        if (leftTime < 0) {
            leftTime = 0L;
        }
        return leftTime;

    }
    private Long getCancelLeftTimeByMinute(Long createTime, int cancelLeftDay) {

        Long cancelTime = createTime + cancelLeftDay * 60;
        Long now = DateUtil.getDateline();
        Long leftTime = cancelTime - now;
        if (leftTime < 0) {
            leftTime = 0L;
        }
        return leftTime;

    }
    /**
     * 转换拼团的 待成团人数
     *
     * @param orderDO 订单do
     * @return 待成团人数
     */
    private int convertOwesNumss(OrderDO orderDO) {
        //取出个性化数据
        String orderData = orderDO.getOrderData();
        Gson gson = new GsonBuilder().create();
        if (!StringUtil.isEmpty(orderData)) {

            //将个性化数据转为map
            Map map = gson.fromJson(orderData, HashMap.class);

            //转换拼团个性化数据
            String json = (String) map.get(OrderDataKey.pintuan.name());
            if (!StringUtil.isEmpty(json)) {
                Map pintuanMap = gson.fromJson(json, HashMap.class);
                Double nums = (Double) pintuanMap.get("owesPersonNums");
                return nums.intValue();
            }
        }

        return 0;
    }

    /**
     * 转换拼团的 待成团人数
     *
     * @param orderDO 订单do
     * @return 待成团人数
     */
    private int convertOwesNums(OrderDO orderDO) {
        //取出个性化数据
        String orderData = orderDO.getOrderData();
        Gson gson = new GsonBuilder().create();
        if (!StringUtil.isEmpty(orderData)) {

            //将个性化数据转为map
            Map map = gson.fromJson(orderData, HashMap.class);

            //转换拼团个性化数据
            String json = (String) map.get(OrderDataKey.pintuan.name());
            if (!StringUtil.isEmpty(json)) {
                Map pintuanMap = gson.fromJson(json, HashMap.class);
                Double nums = (Double) pintuanMap.get("owesPersonNums");
                return nums.intValue();
            }
        }

        return 0;
    }

    @Override
    public OrderDetailVO getModel(String orderSn, OrderDetailQueryParam queryParam) {

        List param = new ArrayList();

        StringBuffer sql = new StringBuffer();
        sql.append("select * from es_order where sn = ? ");
        param.add(orderSn);

        if (queryParam != null && queryParam.getSellerId() != null) {
            sql.append(" and seller_id =?");
            param.add(queryParam.getSellerId());

        } else if (queryParam != null && queryParam.getBuyerId() != null) {
            sql.append(" and member_id=? ");
            param.add(queryParam.getBuyerId());
        }

        OrderDO orderDO = this.daoSupport.queryForObject(sql.toString(), OrderDO.class, param.toArray());
        if (orderDO == null) {
            throw new ServiceException(TradeErrorCode.E453.code(), "订单不存在");
        }

        OrderDetailVO detailVO = new OrderDetailVO();
        BeanUtils.copyProperties(orderDO, detailVO);
        Integer memberId = detailVO.getMemberId();

        // 查询上级团长信息
        DistributionOrderDO distributionOrderDO = distributionOrderManager.getModelByOrderSn(orderSn);
        if(distributionOrderDO != null){
            Integer memberIdLv1 = distributionOrderDO.getMemberIdLv1();
            if(memberIdLv1 != null && memberIdLv1 != 0 ){
                Member member = memberManager.getModel(memberIdLv1);
                if (member != null) {
                    detailVO.setDistributionName(member.getRealName());
                    detailVO.setDistributionMobile(member.getMobile());
                }
            }
        }
        // 查询下单用户信息
        Member member = memberManager.getModel(memberId);
        if(member != null){
            detailVO.setMemberNickName(member.getNickname());
            detailVO.setMemberMobile(member.getMobile());
        }

        // 保存店铺信息
        ShopVO shopVO=shopManager.getShop(detailVO.getSellerId());
        detailVO.setSellerPhone(shopVO.getLinkPhone());
        detailVO.setShopLat(shopVO.getShopLat());
        detailVO.setShopLng(shopVO.getShopLng());
        detailVO.setSellerTown(shopVO.getShopTown());
        String sellerAddress=shopVO.getShopProvince().concat(shopVO.getShopCity()).concat(shopVO.getShopCounty())
                .concat(shopVO.getShopTown()).concat(shopVO.getShopAdd());
        detailVO.setSellerAddress(sellerAddress);

        //判单当前订单是不是服务订单
        //默认当前订单不是服务订单
        detailVO.setIsVirtualOrder(YesOrNoEnums.NO.getIndex());
        //默认不显示核销码按钮，如果在可用时间范围内则显示
        detailVO.setVirtualStatus(YesOrNoEnums.NO.getIndex());
        //如果有过期时间就说明是服务订单
        if (detailVO.getExpiryDay() != null) {
            detailVO.setIsVirtualOrder(YesOrNoEnums.YES.getIndex());
            if(this.queryVerificationStatus(orderDO)!=VerificationCodeStatusEnum.CANCELLED.getIndex()){
                detailVO.setVirtualStatus(YesOrNoEnums.YES.getIndex());
            }

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH, detailVO.getExpiryDay());
            detailVO.setExpiryDayTimestamp(calendar.getTimeInMillis()/1000);
        }

        //初始化sku信息
        List<OrderSkuVO> skuList = JsonUtil.jsonToList(orderDO.getItemsJson(), OrderSkuVO.class);

        //计算在线支付金额 = orderPrice - walletPayPrice
        double onlinePayPrice = detailVO.getOrderPrice();
        Double walletPayPrice = detailVO.getWalletPayPrice();
        if (walletPayPrice != null && walletPayPrice > 0) {
            onlinePayPrice = CurrencyUtil.sub(onlinePayPrice, walletPayPrice);
        }
        detailVO.setOnlinePayPrice(onlinePayPrice < 0 ? 0.0d : onlinePayPrice);

        //订单商品原价
        double goodsOriginalPrice = 0.00;
        // 商品售价，拼团/秒杀/团购时设置的售价
        double goodsSellingPrice = 0.00;

        List<OrderSkuVO> errorSkuList = new ArrayList<>();
        for (OrderSkuVO skuVO : skuList) {
            if(orderDO.getServiceStatus().equals(ServiceStatusEnum.NOT_APPLY.name()) && skuVO.getServiceStatus().equals(ServiceStatusEnum.APPLY.name())){
                errorSkuList.add(skuVO);
                continue;
            }
            //设置商品的可操作状态
            skuVO.setGoodsOperateAllowableVO(new GoodsOperateAllowable(PaymentTypeEnum.valueOf(orderDO.getPaymentType()), OrderStatusEnum.valueOf(orderDO.getOrderStatus()),
                    ShipStatusEnum.valueOf(orderDO.getShipStatus()), ServiceStatusEnum.valueOf(skuVO.getServiceStatus()),
                    PayStatusEnum.valueOf(orderDO.getPayStatus())));

            //计算订单商品原价总和
            goodsOriginalPrice = CurrencyUtil.add(goodsOriginalPrice, CurrencyUtil.mul(skuVO.getOriginalPrice(), skuVO.getNum()));

            goodsSellingPrice=CurrencyUtil.add(goodsSellingPrice,skuVO.getSubtotal());
        }
        detailVO.setGoodsSellingPrice(goodsSellingPrice);
        skuList.removeAll(errorSkuList);

        detailVO.setOrderSkuList(skuList);


        //订单自动取消天数(平台配置)
        int rogLeftDay = getRogLeftDay();
        int cancelLeftDay = getCancelLeftDay();

        //如果未付款并且是在线支付则显示取消时间
        if (!PayStatusEnum.PAY_YES.value().equals(orderDO.getPayStatus())
                && PaymentTypeEnum.ONLINE.value().equals(orderDO.getPaymentType())
                && !OrderStatusEnum.CANCELLED.value().equals(orderDO.getOrderStatus())) {
            //计算自动取消剩余时间
            Long leftTime = getCancelLeftTimeByMinute(orderDO.getCreateTime(), cancelLeftDay);
            detailVO.setCancelLeftTime(leftTime);
        } else {
            detailVO.setCancelLeftTime(0L);
        }
        //如果已发货显示自动确认收货时间
        if (ShipStatusEnum.SHIP_YES.value().equals(orderDO.getShipStatus())) {
            Long leftTime = getCancelLeftTime(orderDO.getShipTime(), rogLeftDay);
            detailVO.setRogLeftTime(leftTime);
        } else {
            detailVO.setRogLeftTime(0L);
        }

        // 初始化订单允许状态
        OrderOperateAllowable operateAllowableVO = new OrderOperateAllowable(detailVO);

        detailVO.setOrderOperateAllowableVO(operateAllowableVO);


        List<OrderMetaDO> metalList = this.orderMetaManager.list(orderSn);


        for (OrderMetaDO metaDO : metalList) {

            //订单的赠品信息
            if (OrderMetaKeyEnum.GIFT.name().equals(metaDO.getMetaKey())) {
                String giftJson = metaDO.getMetaValue();
                if (!StringUtil.isEmpty(giftJson)) {
                    List<FullDiscountGiftDO> giftList = JsonUtil.jsonToList(giftJson, FullDiscountGiftDO.class);
                    detailVO.setGiftList(giftList);
                }
            }

            //使用的积分
            if (OrderMetaKeyEnum.POINT.name().equals(metaDO.getMetaKey())) {
                String pointStr = metaDO.getMetaValue();
                int point = 0;
                if (!StringUtil.isEmpty(pointStr)) {
                    point = Integer.valueOf(pointStr);
                }

                detailVO.setUsePoint(point);

            }


            //赠送的积分
            if (OrderMetaKeyEnum.GIFT_POINT.name().equals(metaDO.getMetaKey())) {
                String giftPointStr = metaDO.getMetaValue();
                int giftPoint = 0;
                if (!StringUtil.isEmpty(giftPointStr)) {
                    giftPoint = Integer.valueOf(giftPoint);
                }

                detailVO.setGiftPoint(giftPoint);

            }


            //满减金额
            if (OrderMetaKeyEnum.FULL_MINUS.name().equals(metaDO.getMetaKey())) {
                Double fullMinus = 0D;
                if (!StringUtil.isEmpty(metaDO.getMetaValue())) {
                    fullMinus = Double.valueOf(metaDO.getMetaValue());
                }
                detailVO.setFullMinus(fullMinus);
            }


            if (OrderMetaKeyEnum.COUPON.name().equals(metaDO.getMetaKey())) {

                String couponJson = metaDO.getMetaValue();
                if (!StringUtil.isEmpty(couponJson)) {
                    List<CouponVO> couponList = JsonUtil.jsonToList(couponJson, CouponVO.class);
                    if (couponList != null && !couponList.isEmpty()) {
                        CouponVO couponVO = couponList.get(0);
                        detailVO.setGiftCoupon(couponVO);
                    }

                }

            }

            //优惠券抵扣金额
            if (OrderMetaKeyEnum.COUPON_PRICE.name().equals(metaDO.getMetaKey())) {
                String couponPriceStr = metaDO.getMetaValue();
                Double couponPrice = 0D;
                if (!StringUtil.isEmpty(couponPriceStr)) {
                    couponPrice = Double.valueOf(couponPriceStr);
                }
                //设置优惠券抵扣金额
                detailVO.setCouponPrice(couponPrice);

            }


        }


        //查询订单优惠券抵扣金额
        String couponPriceStr = this.orderMetaManager.getMetaValue(orderSn, OrderMetaKeyEnum.COUPON_PRICE);
        Double couponPrice = 0D;

        if (!StringUtil.isEmpty(couponPriceStr)) {
            couponPrice = Double.valueOf(couponPriceStr);
        }

        //设置优惠券抵扣金额
        detailVO.setCouponPrice(couponPrice);

        //设置订单的返现金额
        Double cashBack = CurrencyUtil.sub(detailVO.getDiscountPrice(), couponPrice);
        detailVO.setCashBack(cashBack);

        //当商品总价(优惠后的商品单价*数量+总优惠金额)超过商品原价总价
        if (detailVO.getGoodsPrice().doubleValue() > goodsOriginalPrice) {
            detailVO.setGoodsPrice(CurrencyUtil.sub(CurrencyUtil.sub(goodsOriginalPrice, cashBack), couponPrice));
        }
        if (OrderTypeEnum.pintuan.name().equals(detailVO.getOrderType())) {

            //如果订单
            int waitNums = convertOwesNums(orderDO);
            if (waitNums == 0 && PayStatusEnum.PAY_YES.value().equals(detailVO.getPayStatus())) {
                detailVO.setPingTuanStatus("已成团");
            } else if (OrderStatusEnum.CANCELLED.value().equals(detailVO.getOrderStatus())) {
                detailVO.setPingTuanStatus("未成团");
            } else {
                detailVO.setPingTuanStatus("待成团");
            }
        }
        // 社区团购订单提供团长信息
        if (OrderTypeEnum.shetuan.name().equals(detailVO.getOrderType())
                || (OrderTypeEnum.pintuan.name().equals(detailVO.getOrderType()) && YesNoEnum.YES.getIndex() == detailVO.getIsShetuan())) {
            LeaderDO leader = leaderManager.getById(detailVO.getLeaderId());
            detailVO.setLeader(leader);
        }
        // 拼团订单要返回拼团中用户的信息
        if (OrderTypeEnum.pintuan.name().equals(detailVO.getOrderType())) {
            PintuanOrderDetailVo pintuanOrderDetail = pintuanOrderManager.getMainOrderBySn(detailVO.getSn());
            if (!ObjectUtils.isEmpty(pintuanOrderDetail)) {
//                int LackPeopleNum = pintuanOrderDetail.getRequiredNum() - pintuanOrderDetail.getOfferedNum() < 0 ? 0 : pintuanOrderDetail.getRequiredNum() - pintuanOrderDetail.getOfferedNum();
//                pintuanOrderDetail.setLackPeopleNum(LackPeopleNum);
//                pintuanOrderDetail.setLeftTime(pintuanOrderDetail.getEndTime() - DateUtil.getDateline());
                detailVO.setPintuanOrderDetailVo(pintuanOrderDetail);
            }
        }
        // 查询骑手信息
        if("衢山镇".equals(detailVO.getSellerTown()) && "衢山镇".equals(detailVO.getShipTown())){
            Map<String,Object> map = new HashMap<>();
            if(!EnvironmentUtils.isProd()){
                orderSn = "T" + orderSn;
            }
            map.put("upsBillNo",orderSn);
            /**暂停骑手系统,以下代码先注释*/
           /*
            JsonBean riderJson = deliveryManager.queryRider(map);
            if(riderJson.getData() != null){
                JSONObject jsonObject = JSON.parseObject(riderJson.getData().toString());
                detailVO.setRiderName(jsonObject.getString("name"));
                detailVO.setRiderMobile(jsonObject.getString("mobile"));
            }
            */
            detailVO.setRiderName("暂停骑手,要开启请联系");
            detailVO.setMemberMobile("13916510106");
        }
        return detailVO;
    }

    @Override
    public OrderVerificationDTO queryVirtualMessage(String orderSn, Buyer buyer) {

        OrderDO order = this.daoSupport.queryForObject("select * from es_order where sn=?", OrderDO.class, orderSn);
        if (ObjectUtils.isEmpty(buyer) || ObjectUtils.isEmpty(order)  || !buyer.getUid().equals(order.getMemberId())) {
            throw new ServiceException(TradeErrorCode.E459.code(), "订单不存在");
        }
        if (StringUtil.isEmpty(order.getVerificationCode())) {
            throw new ServiceException(TradeErrorCode.E459.code(), "此订单购买的不是虚拟商品");
        }

        // 订单信息
        OrderVerificationDTO orderVerificationDTO = new OrderVerificationDTO();
        BeanUtil.copyProperties(order, orderVerificationDTO);
        orderVerificationDTO.setPayStatusText(PayStatusEnum.valueOf(order.getPayStatus()).description());
        orderVerificationDTO.setOrderStatusText(OrderStatusEnum.valueOf(order.getOrderStatus()).description());


        // 初始化sku信息
        List<OrderSkuVO> skuList = JsonUtil.jsonToList(order.getItemsJson(), OrderSkuVO.class);
        OrderSkuVO orderSkuVO = skuList.get(0);
        GoodsSkuVO sku = goodsSkuManager.getSkuFromCache(orderSkuVO.getSkuId());
        Double mktprice = sku.getMktprice();
        orderVerificationDTO.setMktprice(mktprice);

        orderVerificationDTO.setGoodsId(orderSkuVO.getGoodsId());
        orderVerificationDTO.setSkuId(orderSkuVO.getSkuId());
        orderVerificationDTO.setGoodsName(orderSkuVO.getName());
        orderVerificationDTO.setGoodsImage(orderSkuVO.getGoodsImage());
        orderVerificationDTO.setSpecList(orderSkuVO.getSpecList());

        // 虚拟商品信息
        Double realDiscountMoney;
        if (mktprice == null) {
            realDiscountMoney = 0.0d;
        } else {
            double sub = CurrencyUtil.sub(mktprice, order.getPayMoney());
            realDiscountMoney = sub > 0 ? sub : 0.0d;
        }
        orderVerificationDTO.setRealDiscountMoney(realDiscountMoney);

        Integer expiryDay = order.getExpiryDay();
        if (expiryDay == null) {
            expiryDay = 0;
        }
        orderVerificationDTO.setVerificationStatus(this.queryVerificationStatus(order));

        // 店铺信息
        orderVerificationDTO.setExpiryDate(DateUtil.toString(order.getCreateTime() + expiryDay * 24 * 60 * 60, "yyyy-MM-dd"));
        ShopVO shop = shopManager.getShop(order.getSellerId());
        orderVerificationDTO.setShopId(shop.getShopId());
        orderVerificationDTO.setShopName(shop.getShopName());
        orderVerificationDTO.setShopLogo(shop.getShopLogo());
        orderVerificationDTO.setLinkPhone(shop.getLinkPhone());
        orderVerificationDTO.setShopAdd(shop.getShopAdd());
        orderVerificationDTO.setShopLat(shop.getShopLat());
        orderVerificationDTO.setShopLng(shop.getShopLng());

        // 嵌入二维码的图片路径
//        String imgPath = "G:/qrCode/dog.jpg";
//        //生成二维码
//        try {
//            QRCodeUtil.encode(order.getVerificationCode(), true);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        return orderVerificationDTO;
    }




    /**
     * 读取一个订单详细
     *
     * @param orderId
     * @return
     */
    @Override
    public OrderDO getModel(Integer orderId) {
        return this.daoSupport.queryForObject(OrderDO.class, orderId);
    }


    @Override
    public OrderStatusNumVO getOrderStatusNum(Integer memberId, Integer sellerId) {

        StringBuffer sql = new StringBuffer("select order_type,order_status,pay_status,ship_status,payment_type,comment_status,count(order_id) as count from es_order o ");

        List<Object> term = new ArrayList<>();

        List<String> sqlSplice = new ArrayList<>();
        //按商家查询
        if (sellerId != null) {
            sqlSplice.add("o.seller_id = ? ");
            term.add(sellerId);
        }
        // 按买家查询
        if (memberId != null) {
            sqlSplice.add("o.member_id = ? ");
            term.add(memberId);
        }
        String sqlSplicing = SqlSplicingUtil.sqlSplicing(sqlSplice);
        if (!StringUtil.isEmpty(sqlSplicing)) {
            sql.append(sqlSplicing);
        }
        sql.append(" GROUP BY order_status,pay_status,ship_status,comment_status,payment_type,order_type");

        List<Map<String, Object>> list = this.daoSupport.queryForList(sql.toString(), term.toArray());

        // 所有订单数
        StringBuilder allNumSql = new StringBuilder("select count(order_id) as count from es_order o ");
        if (!StringUtil.isEmpty(sqlSplicing)) {
            allNumSql.append(sqlSplicing);
        }

        OrderStatusNumVO numVO = new OrderStatusNumVO();
        numVO.setWaitShipNum(0);
        numVO.setWaitPayNum(0);
        numVO.setWaitRogNum(0);
        numVO.setCompleteNum(0);
        numVO.setCancelNum(0);
        numVO.setWaitCommentNum(0);
        numVO.setAllNum(this.daoSupport.queryForInt(allNumSql.toString(), term.toArray()));

        // 支付状态未支付，订单状态已确认，为待付款订单
        for (Map map : list) {
            boolean flag = (OrderStatusEnum.CONFIRM.value().equals(map.get("order_status").toString()) && !"COD".equals(map.get("payment_type").toString()))
                    || (OrderStatusEnum.ROG.value().equals(map.get("order_status").toString()) && "COD".equals(map.get("payment_type").toString()));
            if (flag) {
                numVO.setWaitPayNum(numVO.getWaitPayNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }

            // 物流状态为未发货，订单状态为已收款，为待发货订单
            flag = (OrderStatusEnum.CONFIRM.value().equals(map.get("order_status").toString()) && "COD".equals(map.get("payment_type").toString()) )
                    || (OrderStatusEnum.PAID_OFF.value().equals(map.get("order_status").toString()) && !"COD".equals(map.get("payment_type").toString()) );
            if (flag) {
                numVO.setWaitShipNum(numVO.getWaitShipNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }

            // 订单状态为已发货，为待收货订单
            if (OrderStatusEnum.SHIPPED.value().equals(map.get("order_status").toString())) {
                numVO.setWaitRogNum(numVO.getWaitRogNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }

            // 订单状态为已取消，为已取消订单
            if (OrderStatusEnum.CANCELLED.value().equals(map.get("order_status").toString())) {
                numVO.setCancelNum(numVO.getCancelNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }

            // 订单状态为已完成，为已完成订单
            if (OrderStatusEnum.COMPLETE.value().equals(map.get("order_status").toString())) {
                numVO.setCompleteNum(numVO.getCompleteNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }

            // 评论状态为未评论，订单状态为已收货，为待评论订单
            if (CommentStatusEnum.UNFINISHED.value().equals(map.get("comment_status").toString()) && OrderStatusEnum.ROG.value().equals(map.get("order_status").toString())) {
                numVO.setWaitCommentNum(numVO.getWaitCommentNum() + (null == map.get("count") ? 0 : Integer.parseInt(map.get("count").toString())));
            }
        }

        // 申请售后，但未完成售后的订单
        numVO.setRefundNum(this.afterSaleManager.getAfterSaleCount(memberId, sellerId));

        return numVO;

    }

    @Override
    public List<OrderFlowNode> getOrderFlow(String orderSn) {

        OrderDetailVO orderDetailVO = this.getModel(orderSn, null);
        String orderStatus = orderDetailVO.getOrderStatus();
        String paymentType = orderDetailVO.getPaymentType();

        if (orderStatus.equals(OrderStatusEnum.CANCELLED.name())) {
            return OrderFlow.getCancelFlow();
        }

        if (orderStatus.equals(OrderStatusEnum.INTODB_ERROR.name())) {
            return OrderFlow.getIntodbErrorFlow();
        }

        List<OrderFlowNode> resultFlow = OrderFlow.getFlow(orderDetailVO.getOrderType(), paymentType);

        boolean isEnd = false;
        for (OrderFlowNode flow : resultFlow) {

            flow.setShowStatus(1);
            if (isEnd) {
                flow.setShowStatus(0);
            }

            if (flow.getOrderStatus().equals(orderStatus)) {
                isEnd = true;
            }

        }

        return resultFlow;
    }


    @Override
    public Integer getOrderNumByMemberId(Integer memberId) {
        String sql = "select count(0) from es_order where member_id=?";
        Integer num = this.daoSupport.queryForInt(sql, memberId);
        return num;
    }


    @Override
    public Integer getOrderCommentNumByMemberId(Integer memberId, String commentStatus) {
        StringBuffer sql = new StringBuffer("select count(0) from es_order where member_id=? ");

        sql.append(" and ship_status='" + ShipStatusEnum.SHIP_ROG + "' and comment_status = ?  ");

        Integer num = this.daoSupport.queryForInt(sql.toString(), memberId, commentStatus);
        return num;
    }


    @Override
    public List<OrderDetailDTO> getOrderByTradeSn(String tradeSn) {
        List<OrderDetailVO> orderDetailVOList = this.getOrderByTradeSn(tradeSn, null);

        List<OrderDetailDTO> orderDetailDTOList = new ArrayList<>();
        for (OrderDetailVO orderDetailVO : orderDetailVOList) {
            OrderDetailDTO orderDetailDTO = new OrderDetailDTO();
            BeanUtils.copyProperties(orderDetailVO, orderDetailDTO);
            orderDetailDTOList.add(orderDetailDTO);
        }
        return orderDetailDTOList;
    }

    @Override
    public List<OrderDetailVO> getOrderByTradeSn(String tradeSn, Integer memberId) {
        String sql = "select * from es_order where trade_sn = ?";
        List<OrderDetailVO> orderDetailVOList = this.daoSupport.queryForList(sql, OrderDetailVO.class, tradeSn);

        if (orderDetailVOList == null) {
            return new ArrayList<>();
        }
        return orderDetailVOList;
    }

    @Override
    public List<OrderItemsDO> orderItems(String orderSn) {
        return daoSupport.queryForList("select * from es_order_items where order_sn = ?", OrderItemsDO.class, orderSn);
    }

    @Override
    public OrderDetailDTO getModel(String orderSn) {
        OrderDetailVO orderDetailVO = this.getModel(orderSn, null);
        OrderDetailDTO detailDTO = new OrderDetailDTO();
        BeanUtils.copyProperties(orderDetailVO, detailDTO);
        detailDTO.setOrderSkuList(new ArrayList<>());

        for (OrderSkuVO skuVO : orderDetailVO.getOrderSkuList()) {
            OrderSkuDTO skuDTO = new OrderSkuDTO();
            BeanUtil.copyProperties(skuVO, skuDTO);
            detailDTO.getOrderSkuList().add(skuDTO);
        }

        String json = this.orderMetaManager.getMetaValue(detailDTO.getSn(), OrderMetaKeyEnum.GIFT);
        if(!StringUtils.isEmpty(json)){
            List<FullDiscountGiftDO> giftList = JsonUtil.jsonToList(json, FullDiscountGiftDO.class);
            detailDTO.setGiftList(giftList);
        }

        return detailDTO;
    }

    @Override
    public double getOrderRefundPrice(String orderSn) {
        double refundPrice = 0.00;
        List<OrderItemsDO> itemsDOList = this.orderItems(orderSn);
        // 打印日志排查生产上用户取消订单退款金额为0的问题
        logger.debug("退款时查询到的订单详情：" + itemsDOList);

        if (itemsDOList != null && itemsDOList.size() != 0) {
            for (OrderItemsDO itemsDO : itemsDOList) {
                Double goodsRefundPrice = itemsDO.getRefundPrice();
                if(ObjectUtils.isEmpty(goodsRefundPrice)){
                    goodsRefundPrice = 0.0d;
                }
                refundPrice = CurrencyUtil.add(refundPrice, goodsRefundPrice);
            }
        }
        return refundPrice;
    }

    @Override
    public Page queryRefundOrders(RefundQueryParamVO queryParam) {
        // 查询退款订单
        Page<RefundDTO> refundOrderPage = this.afterSaleManager.query(queryParam);
        List<RefundDTO> refundOrders = refundOrderPage.getData();
        List<String> orderSnList =new ArrayList<>();
        Map<String,RefundDO> refundIndex = Maps.newHashMap();
        for (RefundDTO refundOrder : refundOrders) {
            String orderSn = refundOrder.getOrderSn();
            orderSnList.add(orderSn);
            refundIndex.put(orderSn,refundOrder);
        }
        List<OrderDO> orderList = this.loadOrderList(orderSnList);
        // DO 转为 VO
        List<OrderLineVO> lineList = new ArrayList();
        for (OrderDO orderDO : orderList) {
            OrderLineVO line = new OrderLineVO(orderDO);
            RefundDO refundDO = refundIndex.get(orderDO.getSn());
            line.getOrderOperateAllowableVO().setAllowAuditAfterSell(true);
            line.getOrderOperateAllowableVO().setAllowDelete(false);
            line.setRefundStatus(refundDO.getRefundStatus());
            lineList.add(line);
        }
        // 生成新的Page
        long totalCount = refundOrderPage.getDataTotal();
        Page<OrderLineVO> linePage = new Page(queryParam.getPageNo(), totalCount, queryParam.getPageSize(), lineList);
        return linePage;
    }

    @Override
    public Page listOrderDO(OrderQueryParam orderQueryParam) {
        return this.getOrderDOByPage(orderQueryParam);
    }

    @Override
    public List<OrderItemsDO> getOrderItems(List<String> orderSns) {
        List<Object> term = new ArrayList<>();
        String str = SqlUtil.getInSql(orderSns.toArray(), term);
        if (orderSns == null || orderSns.size() == 0) {
            return new ArrayList<>();
        }

        String sql = "select * from es_order_items where order_sn in(" + str + ")";
        return daoSupport.queryForList(sql, OrderItemsDO.class, term.toArray());

    }

    @Override
    public OrderItemsDO queryOrderItem(String orderSn, Integer goodsId) {
        String sql = "SELECT * FROM es_order_items where order_sn=? and goods_id=? ";
        return daoSupport.queryForObject(sql, OrderItemsDO.class, orderSn, goodsId);
    }

    @Override
    public List<OrderItemsDO> getOrderItemsByShipStatus(String orderSn, String shipStatus) {
        String sql = "SELECT * FROM es_order_items where order_sn=? and ship_status=? order by ship_time";
        return daoSupport.queryForList(sql, OrderItemsDO.class, orderSn, shipStatus);
    }

    @Override
    public List<OrderItemsDO> getOrderItems(String orderSn) {
        String sql = "select * from es_order_items where order_sn=?";
        return daoSupport.queryForList(sql, OrderItemsDO.class, orderSn);
    }

    @Override
    public List<OrderItemsDO> getOrderItems(String orderSn, String skuIds) {
        String sql = "select * from es_order_items where order_sn=? and product_id in(" + skuIds + ")";
        return daoSupport.queryForList(sql, OrderItemsDO.class, orderSn);
    }

    @Override
    public List<OrderDO> loadOrderList(List<String> orderSns) {
        List<Object> term = new ArrayList<>();
        String str = SqlUtil.getInSql(orderSns.toArray(), term);
        if (orderSns == null || orderSns.size() == 0) {
            return new ArrayList<>();
        }

        String sql = "select * from es_order where sn in(" + str + ") order by create_time desc";
        return daoSupport.queryForList(sql, OrderDO.class, term.toArray());
    }

    /**
     * 获取今日营业额度
     */
    @Override
    public Double getPayMoney(){
        Integer sellerId = UserContext.getSeller().getSellerId();
        // 当天开始时间时间戳
        long startOfTodDay = DateUtil.startOfTodDay();
        // 当天结束时间时间戳
        long endOfTodDay = DateUtil.endOfTodDay();
        String sql=" SELECT SUM(o.pay_money) as pay_money from es_order o  where o.payment_time >= ?  and o.payment_time<= ? and o.seller_id = ? and o.pay_status = 'PAY_YES' ";
        return  daoSupport.queryForDouble(sql, startOfTodDay, endOfTodDay, sellerId);
    }

    /**
     * 获取今日营业额度
     */
    @Override
    public SortingSerial getSortingSerial(String orderSn){

        String sql="SELECT * from es_sorting_serial where order_sn = ?";
        SortingSerial sortingSerial = this.daoSupport.queryForObject(sql, SortingSerial.class, orderSn);
        return sortingSerial;
    }

    @Override
    public void updatePrintTimes(String orderSn, Integer printTimes) {
        String sql = "update es_order set print_times = ? where sn = ? ";
        this.daoSupport.execute(sql,printTimes,orderSn);
    }

    @Override
    public Page<OrderLineVO> queryOrderAndNicknameList(OrderQueryParam paramDTO) {
        // 分页查询订单
        Page<OrderLineDTO> page = getOrderLineVOByPage(paramDTO);

        //订单自动取消天数(平台配置)
        int cancelLeftDay = getCancelLeftDay();

        // DO 转为 VO
        List<OrderLineDTO> orderList = page.getData();

        List<OrderLineVO> lineList = trimOrderDTO(cancelLeftDay, orderList);

        // 生成新的Page
        long totalCount = page.getDataTotal();
        Page<OrderLineVO> linePage = new Page(paramDTO.getPageNo(), totalCount, paramDTO.getPageSize(), lineList);

        return linePage;
    }

    private Page<OrderLineDTO> getOrderLineVOByPage(OrderQueryParam paramDTO) {
        StringBuffer sql = new StringBuffer("select o.*,m.nickname from es_order o,es_member m " +
                "where o.member_id=m.member_id and o.disabled=0  ");
        //拼接条件
        List<Object> term = composeSql(paramDTO, sql);
        // 先按PO进行查询
        return daoSupport.queryForPage(sql.toString(), paramDTO.getPageNo(), paramDTO.getPageSize(),
                OrderLineDTO.class, term.toArray());
    }

    private List<OrderLineVO> trimOrderDTO(int cancelLeftDay, List<OrderLineDTO> orderList) {
        List<OrderLineVO> lineList = new ArrayList();
        for (OrderLineDTO orderLineDTO : orderList) {
            OrderDO orderDO = new OrderDO();
            BeanUtil.copyProperties(orderLineDTO, orderDO);
            OrderLineVO orderLineVO = new OrderLineVO(orderDO);

            //如果未付款并且是在线支付则显示取消时间
            if (!PayStatusEnum.PAY_YES.value().equals(orderDO.getPayStatus())
                    && PaymentTypeEnum.ONLINE.value().equals(orderDO.getPaymentType())
                    && !OrderStatusEnum.CANCELLED.value().equals(orderDO.getOrderStatus())) {
                //计算自动取消剩余时间
                Long leftTime = getCancelLeftTimeByMinute(orderLineVO.getCreateTime(), cancelLeftDay);
                orderLineVO.setCancelLeftTime(leftTime);
            } else {
                orderLineVO.setCancelLeftTime(0L);
            }

            if (OrderTypeEnum.pintuan.name().equals(orderLineVO.getOrderType())) {
                //如果订单
                int waitNums = convertOwesNumss(orderDO);
                orderLineVO.setWaitingGroupNums(waitNums);
                if (waitNums == 0 && PayStatusEnum.PAY_YES.value().equals(orderLineVO.getPayStatus())) {
                    orderLineVO.setPingTuanStatus("已成团");
                } else if (OrderStatusEnum.CANCELLED.value().equals(orderLineVO.getOrderStatus())) {
                    orderLineVO.setPingTuanStatus("未成团");
                } else {
                    orderLineVO.setPingTuanStatus("待成团");
                }
            }
            orderLineVO.setMemberNickName(orderLineDTO.getNickname());

            if (orderLineDTO.getExpiryDay() != null) {
                orderLineVO.setIsVirtualOrder(YesOrNoEnums.YES.getIndex());
                String orderStatus = orderLineVO.getOrderStatus();
                if (OrderStatusEnum.CANCELLED.value().equals(orderStatus) || OrderStatusEnum.NEW.value().equals(orderStatus)) {
                    orderLineVO.setVirtualStatus(YesOrNoEnums.NO.getIndex());
                } else {
                    orderLineVO.setVirtualStatus(YesOrNoEnums.YES.getIndex());
                }
            }

            lineList.add(orderLineVO);
        }
        return lineList;
    }

    /**
     * 根据会员id 查询是否下过单 订单状态为 已付款
     */
    @Override
    public Integer getOrderNumberByMemberId(Integer memberId,Integer sellerId) {
        String sql = "SELECT count(1) AS order_num FROM es_order WHERE member_id = ? AND seller_id = ? AND pay_status = 'PAY_YES' ";
        return daoSupport.queryForInt(sql,memberId,sellerId);
    }

    @Override
    public void updateOrderFlag(String orderSn, String orderFlag) {
        String sql = "update es_order set order_flag = ? where sn = ?";
        daoSupport.execute(sql,orderFlag,orderSn);
    }

    @Override
    public Integer queryVerificationStatus(OrderDO orderDO) {
        // 1.判断已过期
        Integer expiryDay = orderDO.getExpiryDay();
        if (expiryDay == null) {
            expiryDay = 0;
        }
        long expiryTime = orderDO.getCreateTime() + expiryDay * 24 * 60 * 60;
        if (DateUtil.getDateline() >=  expiryTime) {
            return VerificationCodeStatusEnum.EXPIRED.getIndex();
        }

        // 2.判断未使用
        String orderStatus = orderDO.getOrderStatus();
        String payStatus = orderDO.getPayStatus();
        if (orderStatus.equals(OrderStatusEnum.PAID_OFF.value()) && payStatus.equals(PayStatusEnum.PAY_YES.value())) {
            return VerificationCodeStatusEnum.UNUSED.getIndex();
        }

        //3.判断已使用
        if ((orderStatus.equals(OrderStatusEnum.ROG.value()) || orderStatus.equals(OrderStatusEnum.COMPLETE.value())) && payStatus.equals(PayStatusEnum.PAY_YES.value())) {
            return VerificationCodeStatusEnum.UNUSED.getIndex();
        }

        return VerificationCodeStatusEnum.CANCELLED.getIndex();
    }

    // 根据虚拟订单的核销码查询订单详情
    @Override
    public OrderDetailVO getOrderDetailByVerCode(String verCode,Integer sellerId){
        String sql="select sn from es_order where verification_code = ? and seller_id=?";
        String orderSn=this.daoSupport.queryForString(sql,verCode,sellerId);
        OrderDetailVO orderDetailVO=this.getModel(orderSn,null);

        return orderDetailVO;
    }

    @Override
    public List<OrderDO> getOrderList(List<String> memberIds) {
        List<Object> term = new ArrayList<>();
        String str = SqlUtil.getInSql(memberIds.toArray(), term);
        if (CollectionUtils.isEmpty(memberIds)) {
            return new ArrayList<>();
        }

        String sql = "select * from es_order where sn in(" + str + ") order by create_time desc";
        return daoSupport.queryForList(sql, OrderDO.class, term.toArray());
    }
}
